#include "keydispatcher.h"

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/input.h>
#include <sys/epoll.h>
#include <string.h>


#define MAX_EVENTS 10

struct epoll_event ev;
struct epoll_event events[MAX_EVENTS];
char buffer[sizeof(input_event)];

KeyDispatcher::KeyDispatcher()
{

}

KeyDispatcher::~KeyDispatcher()
{

}

bool KeyDispatcher::init()
{

    bool re = false;
    m_epfd = epoll_create(1);
    if (m_epfd == -1) {
        printf("epoll create fail!\n");
    }
    else {
        m_kdfd = open("/dev/input/event2", O_RDONLY | O_NONBLOCK);
        m_msfd = open("/dev/input/event4", O_RDONLY | O_NONBLOCK);
        if (m_kdfd == -1 || m_msfd == -1) {
            printf("open kd device or mouse fail!\n");
        }
        else {
            ev.data.fd = m_kdfd;
            ev.events = EPOLLIN | EPOLLET;
            int i = epoll_ctl(m_epfd, EPOLL_CTL_ADD, m_kdfd, &ev);
            ev.data.fd = m_msfd;
            ev.events = EPOLLIN | EPOLLET;
            int j = epoll_ctl(m_epfd, EPOLL_CTL_ADD, m_msfd, &ev);
            if (i == -1 || j == -1) {
                printf("add kd device in epoll fail!\n");
            }
            else {
                re = true;
            }
        }
    }

    return re;

}

void KeyDispatcher::doInput(const epoll_event* ev)
{
    ssize_t resize = 0;
    ssize_t n = 0;
    struct input_event input_ev;
    while ((resize = read(ev->data.fd, buffer + n, sizeof(struct input_event))) > 0) {
        n += resize;
        if (n == sizeof(input_event)) {
             memcpy((void*)(&input_ev), buffer, sizeof(input_event));
             m_key.eemit((int)input_ev.type, (int)input_ev.code, (int)input_ev.value);
             n = 0;
         }
    }
}

void KeyDispatcher::run()
{
    //struct input_event input_ev;
    int re = 0;
    while (true) {
        re = epoll_wait(m_epfd, events, MAX_EVENTS, -1);
        for (int i = 0; i < re; ++i) {
             if (events[i].events & EPOLLIN) {
                doInput(events + i);
                    // while (read(events[i].data.fd, &input_ev, sizeof(struct input_event)) == sizeof(struct input_event)) {
                        // printf("type:%d, code:%d, value:%d \n", input_ev.type, input_ev.code, input_ev.value);
                        // m_key.eemit((int)input_ev.type, (int)input_ev.code, (int)input_ev.value);
                    // }
             }
        }
        re = 0;
    }
}

